<script setup lang="ts">
import { ref, reactive, onMounted, h } from "vue";
import { DynamicTable } from "@/components/DynamicTable";
import { TableColumn, PaginationConfig } from "@/components/DynamicTable/types";
import DynamicForm from "@/components/DynamicForm/index.vue";
import type { DynamicFormInstance } from "@/components/DynamicForm/types";
import { FormItemConfig } from "@/components/DynamicForm/types";
import {
  ElMessage,
  ElTag,
  ElButton,
  ElDialog,
  ElDescriptions,
  ElDescriptionsItem,
} from "element-plus";
import { Refresh, Download } from "@element-plus/icons-vue";
import { getStatisticsVulnerabilityDetails } from "../servers";

const props = defineProps<{
  task: string;
}>();

const loading = ref(false);
const vulnerabilityList = ref<any[]>([]);
const searchFormRef = ref<DynamicFormInstance>();

const pagination = reactive<PaginationConfig>({
  currentPage: 1,
  pageSize: 10,
  total: 0,
  pageSizes: [10, 20, 50, 100],
  layout: "total, sizes, prev, pager, next",
  background: true,
});

const searchForm = reactive({
  task_id: "",
  severity: "",
  status: "",
});

const searchConfig: FormItemConfig[] = [
  {
    key: "task_id",
    name: "任务ID",
    type: "input",
    labelWidth: "80px",
    placeholder: "请输入任务ID",
  },
  {
    key: "severity",
    name: "严重程度",
    type: "select",
    labelWidth: "80px",
    placeholder: "选择严重程度",
    params: {
      clearable: true,
      showPlaceholder: false,
      options: [
        { label: "全部", value: "" },
        { label: "严重", value: "critical" },
        { label: "高危", value: "high" },
        { label: "中危", value: "medium" },
        { label: "低危", value: "low" },
      ],
    },
  },
  {
    key: "status",
    name: "状态",
    type: "select",
    labelWidth: "80px",
    placeholder: "选择状态",
    params: {
      clearable: true,
      showPlaceholder: false,
      options: [
        { label: "全部", value: "" },
        { label: "有漏洞", value: "vulnerable" },
        { label: "安全", value: "safe" },
        { label: "错误", value: "error" },
      ],
    },
  },
];

const getSeverityTag = (severity: string) => {
  const severityMap: Record<string, any> = {
    critical: { text: "严重", type: "danger" },
    high: { text: "高危", type: "danger" },
    medium: { text: "中危", type: "warning" },
    low: { text: "低危", type: "info" },
  };
  return severityMap[severity] || { text: severity, type: "info" };
};

// 漏洞详情列表列配置
const vulnerabilityColumns = ref<TableColumn[]>([
  {
    label: "ID",
    prop: "id",
    width: 80,
    show: true,
  },
  {
    label: "攻击类别",
    prop: "attack_category",
    width: 120,
    show: true,
    render: (row) => {
      const categoryMap: Record<string, any> = {
        web_attack: { text: "Web攻击", type: "danger" },
        injection: { text: "注入攻击", type: "danger" },
        xss: { text: "跨站脚本", type: "warning" },
        file_upload: { text: "文件上传", type: "warning" },
        path_traversal: { text: "路径遍历", type: "info" },
      };
      const categoryInfo = categoryMap[row.attack_category] || {
        text: row.attack_category,
        type: "info",
      };
      return h(
        ElTag,
        { type: categoryInfo.type, size: "small" },
        () => categoryInfo.text
      );
    },
  },
  {
    label: "场景名称",
    prop: "scenario_name",
    minWidth: 200,
    show: true,
  },
  {
    label: "威胁类型",
    prop: "threat_type",
    width: 120,
    show: true,
    render: (row) => {
      const threatMap: Record<string, any> = {
        sql_injection: { text: "SQL注入", type: "danger" },
        xss: { text: "XSS", type: "warning" },
        command_injection: { text: "命令注入", type: "danger" },
        file_upload: { text: "文件上传", type: "warning" },
        path_traversal: { text: "路径遍历", type: "info" },
      };
      const threatInfo = threatMap[row.threat_type] || {
        text: row.threat_type,
        type: "info",
      };
      return h(
        ElTag,
        { type: threatInfo.type, size: "small" },
        () => threatInfo.text
      );
    },
  },
  {
    label: "严重程度",
    prop: "severity",
    width: 100,
    show: true,
    render: (row) => {
      const severityInfo = getSeverityTag(row.severity);
      return h(
        ElTag,
        { type: severityInfo.type, size: "small" },
        () => severityInfo.text
      );
    },
  },
  {
    label: "OWASP分类",
    prop: "owasp_category",
    width: 150,
    show: true,
  },
  {
    label: "目标URL",
    prop: "target_url",
    minWidth: 200,
    show: true,
  },
  {
    label: "目标端口",
    prop: "target_port",
    width: 100,
    show: true,
  },
  {
    label: "响应状态",
    prop: "response_status",
    width: 100,
    show: true,
    render: (row) => {
      const status = row.response_status;
      const color =
        status >= 200 && status < 300
          ? "success"
          : status >= 400
          ? "danger"
          : "warning";
      return h(ElTag, { type: color, size: "small" }, status);
    },
  },
  {
    label: "响应时间",
    prop: "response_time",
    width: 100,
    show: true,
    render: (row) => {
      const time = row.response_time || 0;
      return h("span", {}, `${time}ms`);
    },
  },
  {
    label: "检测时间",
    prop: "detected_at",
    width: 180,
    show: true,
  },
  {
    label: "操作",
    prop: "action",
    width: 150,
    fixed: "right",
    show: true,
    slot: "vulnerabilityAction",
  },
]);

const showDetailDialog = ref(false);
const vulnerabilityDetail = ref<any>(null);
const loadingDetail = ref(false);

const fetchVulnerabilityList = async () => {
  loading.value = true;
  try {
    const params: any = {
      page: pagination.currentPage,
      page_size: pagination.pageSize,
      ...searchForm,
    };
    // 移除空值
    Object.keys(params).forEach((key) => {
      if (
        params[key] === "" ||
        params[key] === null ||
        params[key] === undefined
      ) {
        delete params[key];
      }
    });
    const { data } = await getStatisticsVulnerabilityDetails(params);

    vulnerabilityList.value = data?.vulnerabilities || [];
    pagination.total = data?.total || 0;
  } catch (error) {
    ElMessage.error("获取漏洞详情列表失败");
  } finally {
    loading.value = false;
  }
};

const handleSearch = (value: any) => {
  Object.assign(searchForm, value);
  pagination.currentPage = 1;
  fetchVulnerabilityList();
};

const handleSearchReset = () => {
  searchFormRef.value?.resetFields();
  Object.assign(searchForm, {
    task_id: "",
    severity: "",
    status: "",
  });
  pagination.currentPage = 1;
  fetchVulnerabilityList();
};

const handlePageChange = (page: number) => {
  pagination.currentPage = page;
  fetchVulnerabilityList();
};

const handleSizeChange = (size: number) => {
  pagination.pageSize = size;
  pagination.currentPage = 1;
  fetchVulnerabilityList();
};

const handleViewDetail = async (row: any) => {
  loadingDetail.value = true;
  try {
    vulnerabilityDetail.value = row;
    showDetailDialog.value = true;
  } catch (error) {
    ElMessage.error("获取漏洞详情失败");
  } finally {
    loadingDetail.value = false;
  }
};

const handleExport = () => {
  ElMessage.info("导出功能开发中");
};

onMounted(() => {
  fetchVulnerabilityList();
});
</script>

<template>
  <div>
    <el-card shadow="never">
      <div class="search-form-container">
        <DynamicForm
          ref="searchFormRef"
          v-model="searchForm"
          :form-config="searchConfig"
          :gutter="16"
          label-width="100px"
          type="search"
          @search="handleSearch"
          @reset="handleSearchReset"
        />
      </div>
    </el-card>

    <div style="height: 10px"></div>

    <el-card>
      <DynamicTable
        :columns="vulnerabilityColumns"
        :data="vulnerabilityList"
        :loading="loading"
        :pagination="pagination"
        @current-page-change="handlePageChange"
        @size-change="handleSizeChange"
      >
        <template #toolbar-left>
          <el-button type="primary" :icon="Download" @click="handleExport">
            导出漏洞详情
          </el-button>
        </template>

        <template #vulnerabilityAction="{ row }">
          <el-button type="primary" size="small" @click="handleViewDetail(row)">
            详情
          </el-button>
        </template>
      </DynamicTable>
    </el-card>

    <!-- 漏洞详情对话框 -->
    <el-dialog v-model="showDetailDialog" title="漏洞详情" width="900px">
      <el-descriptions
        v-if="vulnerabilityDetail"
        :column="2"
        border
        v-loading="loadingDetail"
      >
        <el-descriptions-item label="ID">{{
          vulnerabilityDetail.id
        }}</el-descriptions-item>
        <el-descriptions-item label="攻击类别">{{
          vulnerabilityDetail.attack_category
        }}</el-descriptions-item>
        <el-descriptions-item label="场景名称">{{
          vulnerabilityDetail.scenario_name
        }}</el-descriptions-item>
        <el-descriptions-item label="威胁类型">{{
          vulnerabilityDetail.threat_type
        }}</el-descriptions-item>
        <el-descriptions-item label="严重程度">
          <el-tag :type="getSeverityTag(vulnerabilityDetail.severity).type">
            {{ getSeverityTag(vulnerabilityDetail.severity).text }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="OWASP分类">{{
          vulnerabilityDetail.owasp_category
        }}</el-descriptions-item>
        <el-descriptions-item label="目标URL" :span="2">{{
          vulnerabilityDetail.target_url
        }}</el-descriptions-item>
        <el-descriptions-item label="目标端口">{{
          vulnerabilityDetail.target_port
        }}</el-descriptions-item>
        <el-descriptions-item label="响应状态">{{
          vulnerabilityDetail.response_status
        }}</el-descriptions-item>
        <el-descriptions-item label="响应时间"
          >{{ vulnerabilityDetail.response_time }}ms</el-descriptions-item
        >
        <el-descriptions-item label="检测时间">{{
          vulnerabilityDetail.detected_at
        }}</el-descriptions-item>
        <el-descriptions-item label="使用的载荷" :span="2">
          <el-input
            :value="vulnerabilityDetail.payload_used"
            type="textarea"
            :rows="2"
            readonly
          />
        </el-descriptions-item>
        <el-descriptions-item label="修复建议" :span="2">
          <el-input
            :value="vulnerabilityDetail.mitigation || '暂无修复建议'"
            type="textarea"
            :rows="3"
            readonly
          />
        </el-descriptions-item>
      </el-descriptions>
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
.search-form-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
</style>
